﻿using Microsoft.Extensions.Logging;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;

namespace LLog
{
    public class LLogProvider : ILoggerProvider
    {
        private readonly string _serverUrl;
        private readonly string _appName;
        public LLogProvider(string serverUrl, string appName)
        {
            _serverUrl = serverUrl;
            _appName = appName;
        }
        public ILogger CreateLogger(string categoryName)
        {
            return new Logger(categoryName, _serverUrl, _appName);
        }
        public void Dispose()
        {

        }
    }
    public class Logger : ILogger
    {
        private readonly string _categoryName;
        private readonly string _serverUrl;
        private readonly string _appName;

        public Logger(string categoryName, string serverUrl, string appName)
        {
            _serverUrl = serverUrl;
            _appName = appName;
            _categoryName = categoryName;
        }

        public bool IsEnabled(LogLevel logLevel)
        {
            return logLevel == LogLevel.Critical || logLevel == LogLevel.Error || logLevel == LogLevel.Warning || logLevel == LogLevel.Information;
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            var client = new RestClient(_serverUrl);
            var request = new RestRequest("/api/logs", Method.POST);
            request.AddJsonBody(new Log()
            {
                AppName = _appName,
                Timestamp = DateTime.Now,
                LogLevel = logLevel.ToString(),
                Message = formatter(state, exception),
                CategoryName = _categoryName
            });
            client.ExecuteAsync(request, response =>
            {
                if (response.StatusCode != HttpStatusCode.OK)
                    throw new Exception(response.Content);
            });
        }
        public IDisposable BeginScope<TState>(TState state)
        {
            return new NoopDisposable();
        }
        private class NoopDisposable : IDisposable
        {
            public void Dispose()
            {
            }
        }
    }
}
